package Engine.AIUGame
{
	import flash.display.BitmapData;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class AISprite extends AIObject
	{
		
		static public const LEFT:uint	= 0x0001;
		static public const RIGHT:uint	= 0x0010;
		
		public var frameWidth:uint;
		public var frameHeight:uint
		
		public var framePixels:BitmapData = null; //实体渲染要显示的位图数据
		public var origin:Point;					//对挤点
		public var frames:uint;
		
		private var _pixels:BitmapData = null; //位图数据
		private var _flipped:uint;				 //翻转标记
		private var _facing:uint;				//面向
		private var _flashRect:Rectangle;
		private var _flashRect2:Rectangle;
		private var _flashPoint:Point;
		private var _flashPointZero:Point;
		
		private var _curAnim:AIAnim = null;
		private var _animCallBack:Function = null;
		
		private var _frameTimer:Number;
		private var _animations:Array = [];
		private var _curFrame:uint;
		private var _curIndex:uint;
		
		private var _finished:Boolean = false; //某动作是否播完
		private var _updateEnabled:Boolean = false; //是否需要重新渲染
		
		
		
		public function AISprite(X:Number = 0,Y:Number = 0,Width:Number = 80,Height:Number = 20)
		{
			super(X,Y,Width,Height);
			x = X;
			y = Y;
			width = frameWidth= Width;
			height = frameHeight = Height;
			
			_flashRect = new Rectangle();
			_flashRect2 = new Rectangle();
			_flashPoint = new Point();
			_flashPointZero = new Point();
			
			origin = new Point();
			
			_facing = RIGHT;
			
		}
		
		public function get pixels():BitmapData
		{
			return _pixels;
		}
		
		/**
		 * 添加一个位图数据到MovieObject
		 * @param Graphic 位图数据
		 * @param Animated 是不是动画
		 * @param Reverse 需不需要翻转
		 * @param Width 动画中每一帧占位图的宽端
		 * @param Height 动画中每一帧占位图的高端
		 */
		public function loadGraphic(Graphic:BitmapData,Animated:Boolean=false,Reverse:Boolean=false,Width:uint=0,Height:uint=0):void
		{
			_pixels = AIGDate.addBitmap(Graphic,Reverse);
			if(Reverse)
				_flipped = _pixels.width>>1;
			else
				_flipped = 0;
			if(Width == 0)
			{
				if(Animated)
					Width = _pixels.height;
				else if(_flipped > 0)
					Width = _pixels.width*0.5;
				else
					Width = _pixels.width;
			}
			width = frameWidth = Width;
			if(Height == 0)
			{
				if(Animated)
					Height = width;
				else
					Height = _pixels.height;
			}
			height = frameHeight = Height;
			resetObjData();
		}
		
		public function makeGraphic(Width:uint,Height:uint,Color:uint=0xffffffff):void
		{
			_pixels = AIGDate.createBitmap(Width,Height,Color);
			width = frameWidth = _pixels.width;
			height = frameHeight = _pixels.height;
			resetObjData();
		}
		
		protected function resetObjData():void
		{
			_flashRect.x = 0;
			_flashRect.y = 0;
			_flashRect.width = frameWidth;
			_flashRect.height = frameHeight;
			_flashRect2.x = 0;
			_flashRect2.y = 0;
			_flashRect2.width = _pixels.width;
			_flashRect2.height = _pixels.height;
			
			if((framePixels == null) || (framePixels.width != width) || (framePixels.height != height))
				framePixels = new BitmapData(width,height);
			origin.x = 0//frameWidth*0.5;
			origin.y = 0//frameHeight;
			framePixels.copyPixels(_pixels,_flashRect,_flashPointZero);
			frames = (_flashRect2.width / _flashRect.width) * (_flashRect2.height / _flashRect.height);
			_curIndex = 0
		}
		/**
		 * 设置源点
		 */
		public function setOrigin(X:Number,Y:Number):void
		{
			origin.x = (X > frameWidth)? frameWidth : X;
			origin.y = (Y > frameHeight)? frameHeight : Y;
		}
		
		/**
		 * 添加动作
		 * @param Name 动作名字 e.g "stand"
		 * @param Frames 动作在位图数据中的Index队列 e.g "1,2,3,6"
		 * @param FrameRate 播放速度
		 * @param Looped 是否循环播放
		 */
		public function addAnimation(Name:String, Frames:Array, FrameRate:Number=0,Looped:Boolean=true):void
		{
			_animations.push(new AIAnim(Name,Frames,FrameRate,Looped));
		}
		
		public function play(AnimName:String,backFun:Function = null):void
		{
			if(_curAnim != null && AnimName == _curAnim.name)
				return;
			_animCallBack = backFun;
			
			_curFrame = 0;
			_curIndex = 0;
			_frameTimer = 0;
			_finished = false;
			var i:uint = 0;
			var l:uint = _animations.length;
			while(i < l)
			{
				if(_animations[i].name == AnimName)
				{
					_curAnim = _animations[i];
					if(_curAnim.delay <= 0)
						_finished = true;
					else
						_finished = false;
					_curIndex = _curAnim.frames[_curFrame];
					_updateEnabled = true;
					return;
				}
				i++;
			}
		}
		
		public function get facing():uint
		{
			return _facing;
		}
		
		public function set facing(value:uint):void
		{
			if(_facing != value)
				_updateEnabled = true;
			_facing = value;
		}
		
		private function updateAnimation():void
		{
			if((_curAnim != null) && (_curAnim.delay > 0) )
			{
				_frameTimer += AIGDate.elapsed;
				while(_frameTimer > _curAnim.delay)
				{
					_frameTimer = _frameTimer - _curAnim.delay;
					if(_curFrame == _curAnim.frames.length-1)
					{
						if(_curAnim.looped)
							_curFrame = 0;
						_finished = true;
					}
					else
						_curFrame++;
					_curIndex = _curAnim.frames[_curFrame];
					_updateEnabled = true;
				}
			}
			
			if(_updateEnabled)
				renderCashFrame();
		}
		
		protected function renderCashFrame():void
		{
			var indexX:uint = _curIndex*frameWidth;
			var indexY:uint = 0;
			
			//Handle sprite sheets
			var widthHelper:uint = _flipped?_flipped:_pixels.width;
			if(indexX >= widthHelper)
			{
				indexY = uint(indexX/widthHelper)*frameHeight;
				indexX %= widthHelper;
			}
			
			//handle reversed sprites
			if(_flipped && (_facing == LEFT))
				indexX = (_flipped<<1)-indexX-frameWidth;
			
			//Update display bitmap
			_flashRect.x = indexX ;
			_flashRect.y = indexY;
			framePixels.copyPixels(_pixels,_flashRect,_flashPointZero);
			_flashRect.x = _flashRect.y = 0;
			
			if(_finished == true && _animCallBack != null)
			{
				var s:String = _curAnim.name;
				if(_curAnim.looped == false)
					_curAnim = null;
				_animCallBack(s);
			}
			
			_updateEnabled = false;
		}
		
		override public function postUpdate():void
		{
			super.postUpdate();
			updateAnimation();
		}
		
		override public function draw():void
		{
			if(_updateEnabled)
				renderCashFrame();
			
			var camera:AIView = AIGDate.GameView;
			_flashPoint.x = x - origin.x - camera.scroll.x;
			_flashPoint.y = y - origin.y - camera.scroll.y;
			camera.buffer.copyPixels(framePixels,_flashRect,_flashPoint,null,null,true);
				
		}
		
	}
}